﻿using H.Logs;
using System;
using System.Diagnostics;
using System.Text;

namespace H.Logger.Logs
{
    /// <summary>
    /// 日志客户端
    /// </summary>
    public class HLogClient : ILog
    {
        /// <summary>
        /// 存储日志收集器
        /// </summary>
        private readonly HLogCollector Collector;

        /// <summary>
        /// 存储当前日志的所处类的名称(日志的一部分信息)
        /// </summary>
        private readonly string ClassName;


        public HLogClient(HLogCollector collector, string sourceName)
        {
            Collector = collector;
            ClassName = sourceName;
        }

        public override void Debug(string message)
        {
            HLogInfo info = new HLogInfo
            {
                Message = message,
                Level = "DEBUG",
                ClassName = ClassName,
                DateTime = DateTime.Now,
                Exception = null,
                StackTrace = null
            };
            Collector.PushLog(info);
        }

        /// <summary>
        /// 反射获取对象中的所有字段,并显示
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        private string PrintObj(object obj)
        {
            if (obj != null)
            {
                StringBuilder sb = new StringBuilder("\r\n对象内容打印如下:\r\n");
                Type type = obj.GetType();
                if (type.IsArray)
                {
                    switch (type.GetArrayRank())
                    {
                        case 1:
                            foreach (object o in (object[])obj)
                            {
                                sb.AppendLine(o.ToString());
                            }
                            break;
                        case 2:
                            foreach (object o in (object[,])obj)
                            {
                                sb.AppendLine(o.ToString());
                            }
                            break;
                        default:
                            sb.AppendLine("无法正常打印的数组:").Append(obj);
                            break;
                    }
                }
                else
                {
                    sb.AppendLine("对象字段");
                    foreach (System.Reflection.FieldInfo field in type.GetFields())
                    {
                        sb.AppendFormat("{0}={1}\r\n", field.Name, field.GetValue(obj));
                    }
                }
                return sb.ToString();
            }
            else
            {
                return "\r\n打印的对象为:NULL";
            }
        }

        public override void Debug(string message, object obj)
        {
            HLogInfo info = new HLogInfo
            {
                Message = message + PrintObj(obj),
                Level = "DEBUG",
                ClassName = ClassName,
                DateTime = DateTime.Now,
                Exception = null,
                StackTrace = null
            };
            Collector.PushLog(info);
        }

        public override void Debug(string message, Exception exception)
        {
            HLogInfo info = new HLogInfo
            {
                Message = message,
                Level = "DEBUG",
                ClassName = ClassName,
                DateTime = DateTime.Now,
                Exception = exception,
                StackTrace = null
            };
            Collector.PushLog(info);
        }

        public override void Debug(string message, StackTrace stackTrace)
        {
            HLogInfo info = new HLogInfo
            {
                Message = message,
                Level = "DEBUG",
                ClassName = ClassName,
                DateTime = DateTime.Now,
                Exception = null,
                StackTrace = stackTrace
            };
            Collector.PushLog(info);
        }

        public override void Error(string message)
        {
            HLogInfo info = new HLogInfo
            {
                Message = message,
                Level = "ERROR",
                ClassName = ClassName,
                DateTime = DateTime.Now,
                Exception = null,
                StackTrace = null
            };
            Collector.PushLog(info);
        }

        public override void Error(string message, Exception exception)
        {
            HLogInfo info = new HLogInfo
            {
                Message = message,
                Level = "ERROR",
                ClassName = ClassName,
                DateTime = DateTime.Now,
                Exception = exception,
                StackTrace = null
            };
            Collector.PushLog(info);
        }

        public override void Error(string message, StackTrace stackTrace)
        {
            HLogInfo info = new HLogInfo
            {
                Message = message,
                Level = "ERROR",
                ClassName = ClassName,
                DateTime = DateTime.Now,
                Exception = null,
                StackTrace = stackTrace
            };
            Collector.PushLog(info);
        }

        public override void Error(string message, Exception exception, StackTrace stackTrace)
        {
            HLogInfo info = new HLogInfo
            {
                Message = message,
                Level = "ERROR",
                ClassName = ClassName,
                DateTime = DateTime.Now,
                Exception = exception,
                StackTrace = stackTrace
            };
            Collector.PushLog(info);
        }

        public override void Info(string message)
        {
            HLogInfo info = new HLogInfo
            {
                Message = message,
                Level = "INFO",
                ClassName = ClassName,
                DateTime = DateTime.Now,
                Exception = null,
                StackTrace = null
            };
            Collector.PushLog(info);
        }

        public override void Warn(string message)
        {
            HLogInfo info = new HLogInfo
            {
                Message = message,
                Level = "WARN",
                ClassName = ClassName,
                DateTime = DateTime.Now,
                Exception = null,
                StackTrace = null
            };
            Collector.PushLog(info);
        }
    }
}
